package net.siufung.core.model;

import net.siufung.core.utils.StringPool;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author 陈建峰
 * @since 2022/6/8 2:11 下午
 */
public interface IEnum<E> {

    /**
     * 枚举选项的值
     *
     * @return 枚举的值
     */
    E getValue();

    /**
     * 枚举字典选项的文本,通常为中文
     *
     * @return 枚举的文本
     */
    default String getDesc() {
        return StringPool.EMPTY;
    };

    /**
     * 从指定的枚举类中查找想要的枚举
     *
     * @param type      实现了 {@link IEnum} 的枚举类
     * @param predicate 判断逻辑
     * @param <T>       枚举类型
     * @return 查找到的结果
     */
    static <T extends IEnum<?>> T get(Class<T> type, Predicate<T> predicate) {
        if (type.isEnum()) {
            for (T enumsDict :type.getEnumConstants()) {
                if (predicate.test(enumsDict)) {
                    return enumsDict;
                }
            }
        }
        return null;
    }

    /**
     * 从指定的枚举类中比对结果枚举
     *
     * @param type      实现了 {@link IEnum} 的枚举类
     * @param predicate 判断逻辑
     * @param <T>       枚举类型
     * @return 结果是否成立
     */
    static <T extends IEnum<?>> Boolean exist(Class<T> type, Predicate<T> predicate) {
        if (type.isEnum()) {
            for (T enumsDict :type.getEnumConstants()) {
                if (predicate.test(enumsDict)) {
                    return Boolean.TRUE;
                }
            }
        }
        return Boolean.FALSE;
    }

    /**
     * 从指定的枚举类中查找想要的枚举的描述信息
     * @param type 实现了 {@link IEnum} 的枚举类
     * @param predicate 判断逻辑
     * @param <T> 枚举类型
     * @return 查找到的结果
     */
    static <T extends IEnum<?>> String getDesc(Class<T> type, Predicate<T> predicate) {
        if (type.isEnum()) {
            for (T enumsDict :type.getEnumConstants()) {
                if (predicate.test(enumsDict)) {
                    return Optional.ofNullable(enumsDict)
                            .map(e -> enumsDict.getDesc()).orElse(StringPool.EMPTY);
                }
            }
        }
        return StringPool.EMPTY;
    }

    /**
     * 从指定的枚举类中查找想要的枚举集合
     * @param type 实现了 {@link IEnum} 的枚举类
     * @param predicate 判断逻辑
     * @param <T> 枚举类型
     * @return 查找到的结果
     */
    static <T extends IEnum<?>> List<T> findList(Class<T> type, Predicate<T> predicate) {
        if (type.isEnum()) {
            return Arrays.stream(type.getEnumConstants())
                    .filter(predicate)
                    .collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    /**
     * 从指定的枚举类中查找想要的枚举集合
     * @param type 实现了 {@link IEnum} 的枚举类
     * @param <T> 枚举类型
     * @return 查找到的结果
     */
    static <T extends IEnum<?>> List<T> findList(Class<T> type) {
        if (type.isEnum()) {
            return Arrays.stream(type.getEnumConstants())
                    .collect(Collectors.toList());
        }
        return Collections.emptyList();
    }


}
